package dexter.core.coord;

import java.util.Collection;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;

import dexter.core.common.HostParams;
import dexter.core.common.HostResult;
import dexter.exception.NodeNotCreatedException;
import dexter.exception.TimeoutException;
import dexter.net.Producer;
import dexter.net.msg.common.RequestParams;

import dexter.aware.Selector;
import dexter.aware.policy.StatePolicy;

public class HostCreator {
	
	private Collection<Producer> producers;
	private final int TIMEOUT = 30;
	
	public HostCreator() {
		producers = new Vector<Producer>();
	}
	
	public Vector<String> createRemoteGroup(Properties props, String classname, byte[] classbytes) {
		
		Vector<String> urls = new Vector<String>();
		int number = Integer.parseInt(props.getProperty("number"));
		int port = Integer.parseInt(props.getProperty("port"));
		//int port = Host.PORT;
		StatePolicy policy = new StatePolicy(new int[]{5,5,5});
		Hashtable<String,int[]>  hosts = Selector.selectHostsByTime(number, 2, policy);
		
        for (String host: hosts.keySet()) {
			Producer producer = new Producer(host, port);
			try {
				String url = createRemoteServer(producer, props, classname, classbytes);
			    urls.add(url);
			} catch (Exception e) {
				e.printStackTrace();
			}
			producers.add(producer);
        }	
        return urls;
	}

	private String createRemoteServer(Producer producer, Properties props, String classname, byte[] classbytes) throws TimeoutException, NodeNotCreatedException {
		
		RequestParams nparams = new HostParams(props, classname, classbytes);
		HostListener nlistener = new HostListener();
		
		producer.send(nparams, nlistener);

		int count = 0;
		while(!nlistener.hasResult() && count < TIMEOUT) {
			try { Thread.sleep(1000); } catch (Exception e) {}
			count++;
		}
		
		if (count>=TIMEOUT) throw new TimeoutException("Timeout waiting for test initialization, is the coordinator server active?");
		
		HostResult result = nlistener.getResult();
		if (result==null) throw new NodeNotCreatedException("Result is null");
		
		boolean ok = result.isOk();
		
		if (!ok) throw new NodeNotCreatedException("Node has not been created");
		
		String url = result.getUrl();
		
		return url;
		
	}

}
